#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "sqlite3.h"
#include "database.h"
#include "packages.h"
#include "users.h"
#include "notification.h"
#include "part1.h"

// 全局变量，存储用户链表
struct users* g_users_list = NULL;

// 初始化用户列表
void init_users_for_notification(const char* filename) {
    if (g_users_list) {
        freeUsers(g_users_list); // 如果已经存在，先释放
    }
    g_users_list = loadUsersFromFile(filename);
}

// 根据用户名在链表中查找用户
struct users* find_user_by_username(const char* username) {
    struct users* current = g_users_list;
    while (current != NULL) {
        if (strcmp(current->username, username) == 0) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

// 根据手机号在链表中查找用户
struct users* find_user_by_phone(const char* phone) {
    struct users* current = g_users_list;
    while (current != NULL) {
        if (strcmp(current->phonenumber, phone) == 0) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

// 发送通知函数
int send_notification(const char *receiver, const char *sender, const char *type, const char *content) {
    sqlite3_stmt *stmt;
    const char *query = "INSERT INTO notifications (receiver, sender, type, content) VALUES (?, ?, ?, ?)";
    

    if (sqlite3_prepare_v2(db, query, -1, &stmt, NULL) != SQLITE_OK) {
        printf("准备发送通知语句失败: %s\n", sqlite3_errmsg(db));
        return 0;
    }
    
    // 检查接收者是否存在
    if (!find_user_by_username(receiver)) {
        printf("接收者用户名不存在: %s\n", receiver);
        sqlite3_finalize(stmt);
        return 0;
    }
    
    sqlite3_bind_text(stmt, 1, receiver, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 2, sender ? sender : "system", -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 3, type, -1, SQLITE_STATIC);
    sqlite3_bind_text(stmt, 4, content, -1, SQLITE_STATIC);
    
    int result = (sqlite3_step(stmt) == SQLITE_DONE);
    sqlite3_finalize(stmt);
    
    return result;
}

// 获取用户的所有通知
int get_user_notifications(const char *username, int (*callback)(void*, int, char**, char**), void *user_data) {
    const char *query = "SELECT id, sender, type, content, is_read, created_at FROM notifications "
                        "WHERE receiver = ? ORDER BY created_at DESC";
    sqlite3_stmt *stmt;

    if (sqlite3_prepare_v2(db, query, -1, &stmt, NULL) != SQLITE_OK) {
        printf("准备获取通知语句失败: %s\n", sqlite3_errmsg(db));
        return 0;
    }

    sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);

    while (sqlite3_step(stmt) == SQLITE_ROW) {
        char *argv[6];
        for (int i = 0; i < 6; i++) {
            argv[i] = (char *)sqlite3_column_text(stmt, i);
        }
        callback(user_data, 6, argv, NULL);
    }

    sqlite3_finalize(stmt);
    return 1;
}

// 获取用户未读通知数量
int get_unread_notification_count(const char *username) {
    char query[256];
    sprintf(query, "SELECT COUNT(*) FROM notifications WHERE receiver = '%s' AND is_read = 0", username);
    
    sqlite3_stmt *stmt;
    int count = 0;
    
    if (sqlite3_prepare_v2(db, query, -1, &stmt, NULL) == SQLITE_OK) {
        if (sqlite3_step(stmt) == SQLITE_ROW) {
            count = sqlite3_column_int(stmt, 0);
        }
        sqlite3_finalize(stmt);
    } else {
        printf("获取未读通知数量失败: %s\n", sqlite3_errmsg(db));
    }
    
    return count;
}

// 将通知标记为已读
int mark_notification_as_read(int notification_id) {
    char query[256];
    sprintf(query, "UPDATE notifications SET is_read = 1 WHERE id = %d", notification_id);
    
    char *err_msg = NULL;
    int result = sqlite3_exec(db, query, NULL, NULL, &err_msg);
    
    if (result != SQLITE_OK) {
        printf("标记通知为已读失败: %s\n", err_msg);
        sqlite3_free(err_msg);
        return 0;
    }
    
    return 1;
}

// 将用户所有通知标记为已读
int mark_all_notifications_as_read(const char *username) {
    char query[256];
    sprintf(query, "UPDATE notifications SET is_read = 1 WHERE receiver = '%s'", username);
    
    char *err_msg = NULL;
    int result = sqlite3_exec(db, query, NULL, NULL, &err_msg);
    
    if (result != SQLITE_OK) {
        printf("标记所有通知为已读失败: %s\n", err_msg);
        sqlite3_free(err_msg);
        return 0;
    }
    
    return 1;
}

// 删除特定通知
int delete_notification(int notification_id) {
    char query[256];
    sprintf(query, "DELETE FROM notifications WHERE id = %d", notification_id);
    
    char *err_msg = NULL;
    int result = sqlite3_exec(db, query, NULL, NULL, &err_msg);
    
    if (result != SQLITE_OK) {
        printf("删除通知失败: %s\n", err_msg);
        sqlite3_free(err_msg);
        return 0;
    }
    
    return 1;
}

// 删除用户的所有通知
int delete_all_user_notifications(const char *username) {
    char query[256];
    sprintf(query, "DELETE FROM notifications WHERE receiver = '%s'", username);
    
    char *err_msg = NULL;
    int result = sqlite3_exec(db, query, NULL, NULL, &err_msg);
    
    if (result != SQLITE_OK) {
        printf("删除用户所有通知失败: %s\n", err_msg);
        sqlite3_free(err_msg);
        return 0;
    }
    
    return 1;
}

// 发送系统通知给所有用户 - 修改为使用链表
int broadcast_notification(const char *type, const char *content) {
    // 先检查链表是否初始化
    if (!g_users_list) {
        printf("用户列表未初始化，无法发送广播通知\n");
        return 0;
    }
    
    int success_count = 0;
    int total_count = 0;
    struct users* current = g_users_list;
    
    while (current != NULL) {
        if (send_notification(current->username, "system", type, content)) {
            success_count++;
        }
        total_count++;
        current = current->next;
    }
    
    return (success_count > 0);
}

// 获取包裹基本信息
int get_package_info(long package_id, char **recipient_phone, char **item_name) {
    sqlite3_stmt *stmt;
    const char *package_query = "SELECT recipient_phone, item_name FROM packages WHERE package_id = ?";
    int success = 0;
    
    if (sqlite3_prepare_v2(db, package_query, -1, &stmt, NULL) != SQLITE_OK) {
        printf("准备查询包裹信息语句失败: %s\n", sqlite3_errmsg(db));
        return 0;
    }
    
    sqlite3_bind_int64(stmt, 1, package_id);
    
    if (sqlite3_step(stmt) == SQLITE_ROW) {
        const char *phone = (const char *)sqlite3_column_text(stmt, 0);
        const char *name = (const char *)sqlite3_column_text(stmt, 1);
        
        if (phone && name) {
            *recipient_phone = strdup(phone);
            *item_name = strdup(name);
            success = 1;
        }
    }
    
    sqlite3_finalize(stmt);
    return success;
}

// 根据手机号查找用户名 - 修改为使用链表
char* find_username_by_phone(const char *phone_number) {
    struct users* user = find_user_by_phone(phone_number);
    
    if (user) {
        return strdup(user->username);
    }
    
    return NULL;
}

// 发送包裹状态变更通知
int notify_package_status_change(long package_id, int new_status) {
    if (!g_users_list) {
        init_users_for_notification("users.txt"); // 用户数据文件名为users.txt
        if (!g_users_list) {
            printf("无法加载用户数据，通知系统不可用\n");

            return 0;
        }
    }
    char *recipient_phone = NULL;
    char *item_name = NULL;
    char *username = NULL;
    char notification_content[512];
    int success = 0;
    
    // 1. 获取包裹信息
    if (!get_package_info(package_id, &recipient_phone, &item_name)) {
        printf("未找到包裹信息 (ID: %ld)\n", package_id);
        return 0;
    }
    
    // 2. 找到对应的用户名
    username = find_username_by_phone(recipient_phone);
    if (!username) {
        printf("未找到与手机号 %s 关联的用户\n", recipient_phone);
        free(recipient_phone);
        free(item_name);
        return 0;
    }
    
    // 3. 生成并发送通知
    if (new_status != 3 && new_status != 5){
        sprintf(notification_content, "您的包裹 \"%s\"(编号: %ld) 状态已更新为: %s", 
                item_name, package_id, get_status_text(new_status));
        
        success = send_notification(username, "system", "package_status", notification_content);
    }

    if (new_status == 5) {
        sprintf(notification_content, "您的包裹 \"%s\"(编号: %ld) 状态已更新为: %s, 请及时联系快递员了解详细情况", 
            item_name, package_id, get_status_text(new_status));
    
        success = send_notification(username, "system", "package_status", notification_content);
    }
    
    // 4. 清理资源
    free(recipient_phone);
    free(item_name);
    free(username);
    cleanup_notification_system();
    return success;
}


// 发送包裹状态变更和发送取件码
int notify_package_status_change_and_claim_code(long package_id, int new_status, const char *claim_code) {
    if (!g_users_list) {
        init_users_for_notification("users.txt"); // 用户数据文件名为users.txt
        if (!g_users_list) {
            printf("无法加载用户数据，通知系统不可用\n");

            return 0;
        }
    }
    char *recipient_phone = NULL;
    char *item_name = NULL;
    char *username = NULL;
    char notification_content[512];
    int success = 0;
    
    // 1. 获取包裹信息
    if (!get_package_info(package_id, &recipient_phone, &item_name)) {
        printf("未找到包裹信息 (ID: %ld)\n", package_id);
        return 0;
    }
    
    // 2. 找到对应的用户名
    username = find_username_by_phone(recipient_phone);
    if (!username) {
        printf("未找到与手机号 %s 关联的用户\n", recipient_phone);
        free(recipient_phone);
        free(item_name);
        return 0;
    }
    
    // 3. 生成并发送通知
    if (new_status != 3 && new_status != 5){
        sprintf(notification_content, "您的包裹 \"%s\"(编号: %ld) 状态已更新为: %s", 
                item_name, package_id, get_status_text(new_status));
        
        success = send_notification(username, "system", "package_status", notification_content);
    }

    if (new_status == 5) {
        sprintf(notification_content, "您的包裹 \"%s\"(编号: %ld) 状态已更新为: %s, 请及时联系快递员了解详细情况", 
            item_name, package_id, get_status_text(new_status));
    
        success = send_notification(username, "system", "package_status", notification_content);
    }

    if (new_status == 3) {
        sprintf(notification_content, "您的包裹 \"%s\"(编号: %ld) 状态已更新为: %s, 取件码为: %s", 
                item_name, package_id, get_status_text(new_status), claim_code);
        
        success = send_notification(username, "system", "package_status", notification_content);
    }
    
    // 4. 清理资源
    free(recipient_phone);
    free(item_name);
    free(username);
    cleanup_notification_system();
    return success;
}


// 管理员发送系统通告
int admin_send_announcement(const char *admin_username, const char *title, const char *content) {
    char full_content[1024];
    sprintf(full_content, "【%s】%s", title, content);
    
    int result = broadcast_notification("announcement", full_content);
    
    if (result) {
        printf("管理员 %s 成功发送系统通告: %s\n", admin_username, title);
    } else {
        printf("发送系统通告失败\n");
    }
    
    return result;
}

// 发送优惠券通知给用户
int send_coupon_notification(const char *username, double discount_rate, int count) {
    char notification_content[512];
    int discount_percent = (int)(discount_rate * 100);
    
    sprintf(notification_content, "恭喜！您获得了 %d 张新的优惠券，可享受 %d%% 的折扣。请在下次下单时使用。", 
            count, discount_percent);
    
    int result = send_notification(username, "system", "coupon", notification_content);
    
    if (result) {
        printf("成功向用户 %s 发送优惠券通知\n", username);
    } else {
        printf("向用户 %s 发送优惠券通知失败\n", username);
    }
    
    return result;
}

// 辅助函数：构建查询通知的SQL语句
char* build_notification_query(const char *username, const char *type) {
    char *query;
    
    if (type && strcmp(type, "") != 0) {
        // 带类型过滤的查询
        query = malloc(sizeof(char) * 256);
        sprintf(query, "SELECT id, sender, type, content, is_read, created_at FROM notifications "
                      "WHERE receiver = '%s' AND type = '%s' ORDER BY created_at DESC", 
                      username, type);
    } else {
        // 不过滤类型的查询
        query = malloc(sizeof(char) * 200);
        sprintf(query, "SELECT id, sender, type, content, is_read, created_at FROM notifications "
                      "WHERE receiver = '%s' ORDER BY created_at DESC", 
                      username);
    }
    
    return query;
}

// 用户查看指定类型的通知
int get_notifications_by_type(const char *username, const char *type, 
                             int (*callback)(void*, int, char**, char**), void *user_data) {
    if (!username || !callback) {
        return 0;
    }
    
    // 构建查询语句
    char *query = build_notification_query(username, type);
    if (!query) {
        printf("构建查询通知语句失败\n");
        return 0;
    }
    
    // 执行查询
    char *err_msg = NULL;
    int result = sqlite3_exec(db, query, callback, user_data, &err_msg);
    
    if (result != SQLITE_OK) {
        printf("获取通知失败: %s\n", err_msg);
        sqlite3_free(err_msg);
        free(query);
        return 0;
    }
    
    free(query);
    return 1;
}

// 获取可用的通知类型
int get_notification_types(int (*callback)(void*, int, char**, char**), void *user_data) {
    const char *query = "SELECT DISTINCT type FROM notifications";
    char *err_msg = NULL;
    
    int result = sqlite3_exec(db, query, callback, user_data, &err_msg);
    
    if (result != SQLITE_OK) {
        printf("获取通知类型失败: %s\n", err_msg);
        sqlite3_free(err_msg);
        return 0;
    }
    
    return 1;
}

// 查看通知的回调函数
int print_notification_callback(void *data, int argc, char **argv, char **azColName) {
    int *count = (int*)data;
    (*count)++;
    
    const char *id = argv[0] ? argv[0] : "N/A";
    const char *sender = argv[1] ? argv[1] : "系统";
    const char *type = argv[2] ? argv[2] : "未知";
    const char *content = argv[3] ? argv[3] : "";
    const char *is_read = (argv[4] && strcmp(argv[4], "1") == 0) ? "已读" : "未读";
    const char *time = argv[5] ? argv[5] : "未知时间";
    
    // 转换通知类型为中文
    const char *type_text = "未知";
    if (strcmp(type, "announcement") == 0) {
        type_text = "系统公告";
    } else if (strcmp(type, "package_status") == 0) {
        type_text = "包裹状态";
    } else if (strcmp(type, "coupon") == 0) {
        type_text = "优惠券";
    }
    
    printf("\n------- 通知 #%s (%s) -------\n", id, is_read);
    printf("发送者: %s\n", sender);
    printf("类型: %s\n", type_text);
    printf("内容: %s\n", content);
    printf("时间: %s\n", time);
    
    return 0;
}

// 显示通知类型的回调函数
int print_notification_type_callback(void *data, int argc, char **argv, char **azColName) {
    int *count = (int*)data;
    (*count)++;
    
    const char *type = argv[0] ? argv[0] : "未知";
    const char *type_text = "未知";
    
    if (strcmp(type, "announcement") == 0) {
        type_text = "系统公告";
    } else if (strcmp(type, "package_status") == 0) {
        type_text = "包裹状态";
    } else if (strcmp(type, "coupon") == 0) {
        type_text = "优惠券";
    }
    
    printf("%d. %s (%s)\n", *count, type_text, type);
    
    return 0;
}

// 获取通知类型列表
char** get_notification_type_list(int *count) {
    // 先获取类型数量
    sqlite3_stmt *stmt;
    int type_count = 0;
    const char *count_query = "SELECT COUNT(DISTINCT type) FROM notifications";
    
    if (sqlite3_prepare_v2(db, count_query, -1, &stmt, NULL) == SQLITE_OK) {
        if (sqlite3_step(stmt) == SQLITE_ROW) {
            type_count = sqlite3_column_int(stmt, 0);
        }
        sqlite3_finalize(stmt);
    }
    
    if (type_count == 0) {
        *count = 0;
        return NULL;
    }
    
    // 分配内存存储类型
    char **types = (char**)malloc(sizeof(char*) * (type_count + 1));
    if (!types) {
        *count = 0;
        return NULL;
    }
    
    // 查询所有类型
    const char *type_query = "SELECT DISTINCT type FROM notifications";
    int index = 0;
    
    if (sqlite3_prepare_v2(db, type_query, -1, &stmt, NULL) == SQLITE_OK) {
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            const char *type = (const char*)sqlite3_column_text(stmt, 0);
            if (type) {
                types[index++] = strdup(type);
            }
        }
        sqlite3_finalize(stmt);
    }
    
    types[index] = NULL; // 最后一个元素设为NULL作为结束标记
    *count = index;
    
    return types;
}

// 根据用户类型获取类型名称
const char* get_user_type_name(int user_type) {
    switch (user_type) {
        case 1: return "管理员";
        case 2: return "员工";
        case 3: return "用户";
        default: return "未知类型";
    }
}

// 释放类型列表内存
void free_notification_type_list(char **types, int count) {
    if (!types) return;
    
    for (int i = 0; i < count; i++) {
        if (types[i]) free(types[i]);
    }
    
    free(types);
}



// 清理通知系统资源
void cleanup_notification_system() {
    if (g_users_list) {
        freeUsers(g_users_list);
        g_users_list = NULL;
    }
}
